//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#if !(defined(_GNUC) && defined(_arm))

#include <string.h>
#include <assert.h>
#include <elatypes.h>

EXTERN_C void * __cdecl memcpy(void * pDest, const void * pSource, size_t cb)
{
#ifdef _GNUC

#if defined(_x86)
    int temp0, temp1, temp2;
    ASM("rep;"
        "movsd;"//movs DoubleWord(4 btyes) one time
        "testb $2,%b6;"//0x03H--11b, 0x02H--10b, 0x01H--01b
        "je 1f;"
        "movsw;"
        "1:"
        "testb $1,%b6;"
        "je 2f;"
        "movsb;"
        "2:"
        :"=D" (temp0), "=S" (temp1), "=c" (temp2)
        :"0" ((long)pDest),"1" ((long)pSource), "2" (cb/4), "a" (cb)
        :"memory");
    return pDest;
#endif    //if defined(_x86)

#endif    //ifdef _GNUC

    if (((int)pDest | (int)pSource | cb) & (sizeof(void*)-1)) {
        char* p = (char*) pDest;    // not natural aligned
        char* q = (char*) pSource;
        while (cb--) {
            *p++ = *q++;            // copy one byte at a time
        }
    }
    else {                          // in case of natural alignment
        int* p = (int*) pDest;
        int* q = (int*) pSource;
        int count = cb / sizeof(int);
//        assert(sizeof(int) == 4);   // NOTE: modify for 64 bit machine later

        while (count--) {
            *p++ = *q++;            // copy 4 bytes at a time
        }
    }
    return pDest;
}

#endif
